//
//  NavigationBar.swift
//  
//
//  Created by tank on 2021/12/16.
//

import Foundation
import UIKit
import SnapKit

open class NavigationBar: UIView {
    public typealias OnBackButtonTap = () -> Void
    
    public static let height: CGFloat = 44
    
    public static let backButtonHeight: CGFloat = 32
    
    public static let margin: CGFloat = 6
    
    public static let iconFontPrefix: String = "icon,"
    
    public lazy var backButton: TitleMenuView = {
        let button = TitleMenuView()
        button.titleLabel?.font = IconFonts.shared.iconFont(size: 16)
        button.setTitleColor(tintColor, for: .normal)
        button.setTitle(IconFonts.dataSource?.iconNavigationBack, for: .normal)
        return button
    }()
    
    private lazy var titleLabel: TextLabel = {
        let label = TextLabel()
        label.lineBreakMode = .byTruncatingTail
        label.textColor = tintColor
        label.font = UIFont.boldSystemFont(ofSize: 16)
        return label
    }()
    
    private let leftMenusView: RowView = {
        let rowView = RowView()
        return rowView
    }()
    
    private let rightMenusView: RowView = {
        let rowView = RowView()
        return rowView
    }()
    
    public private(set) var title: String?
    
    public private(set) var subTitle: String?
    
    public override var tintColor: UIColor? {
        get {
            super.tintColor
        }
        
        set {
            super.tintColor = newValue
            
            backButton.setTitleColor(tintColor, for: .normal)
            
            titleLabel.textColor = tintColor
            
            set(title: title, subTitle: subTitle)
        }
    }
    
    
    public var rightMenus: [MenuData]? {
        didSet {
            rightMenusView.subviews.forEach { $0.removeFromSuperview() }
            
            rightMenus?.forEach { menuData in
                let titleMenuView = TitleMenuView()
                titleMenuView.onMenuTap = onMenuTap
                
                rightMenusView.addSubview(titleMenuView)
                titleMenuView.setMenuData(menuData: menuData)
            }
            
            rightMenusView.invalidateIntrinsicContentSize()
            setNeedsUpdateConstraints()
        }
    }
    
    public var titleAlignment: NSTextAlignment {
        set {
            titleLabel.textAlignment = newValue
        }
        
        get {
            return titleLabel.textAlignment
        }
    }
    
    public var onMenuTap: ((_ menuData: MenuData?) -> Void)?
    
    public var onBackButtonTap: OnBackButtonTap?
    
    public init() {
        super.init(frame: CGRect(x: 0, y: 0,
                                 width: UIScreen.main.bounds.width,
                                 height: NavigationBar.height))
        
        backgroundColor = Theme.shared.currentThemeData.navigationBarColor
        tintColor = Theme.shared.currentThemeData.navigationBarTintColor
    }
    
    public required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    open override func didMoveToSuperview() {
        super.didMoveToSuperview()
        
        guard superview != nil else {
            return
        }
        
        initView()
    }
    
    open override func updateConstraints() {
        super.updateConstraints()
        
        initConstraints()
    }
    
    open override func safeAreaInsetsDidChange() {
        super.safeAreaInsetsDidChange()
        
        setNeedsUpdateConstraints()
    }
    
    func initView() {
        addSubview(leftMenusView)
        
        leftMenusView.addSubview(backButton)
        backButton.onMenuTap = { [weak self] menuData in
            guard let onBackButtonTap = self?.onBackButtonTap else {
                self?.ex.viewController?.navigationController?.popViewController(animated: true)
                return
            }
            
            onBackButtonTap()
        }
        
        addSubview(titleLabel)
        
        addSubview(rightMenusView)
        
        initConstraints()
    }
    
    func initConstraints() {
        leftMenusView.snp.remakeConstraints { make in
            make.height.equalTo(NavigationBar.backButtonHeight)
            make.centerY.equalTo(safeAreaInsets.top + NavigationBar.height / 2)
            make.left.equalToSuperview().offset(NavigationBar.margin)
        }
        
        titleLabel.snp.remakeConstraints { make in
            if titleAlignment == .center {
                let leftMenusViewSize: CGSize = leftMenusView
                    .sizeThatFits(CGSize(width: UIView.noIntrinsicMetric,
                                         height: UIView.noIntrinsicMetric))
                let rightMenusViewSize: CGSize = rightMenusView
                    .sizeThatFits(CGSize(width: UIView.noIntrinsicMetric,
                                         height: UIView.noIntrinsicMetric))
                let offset = max(leftMenusViewSize.width, rightMenusViewSize.width)
                
                make.left.equalToSuperview().offset(offset + NavigationBar.margin + NavigationBar.margin)
                make.right.equalToSuperview().offset(-(offset + NavigationBar.margin + NavigationBar.margin))
                make.centerY.equalTo(leftMenusView.snp.centerY)
            } else {
                make.left.equalTo(leftMenusView.snp.right).offset(NavigationBar.margin)
                make.right.equalTo(rightMenusView.snp.left).offset(-NavigationBar.margin)
                make.centerY.equalTo(leftMenusView.snp.centerY)
            }
        }
        
        rightMenusView.setContentCompressionResistancePriority(.required, for: .horizontal)
        rightMenusView.snp.remakeConstraints { make in
            make.right.equalToSuperview().offset(-NavigationBar.margin)
            make.centerY.equalTo(leftMenusView.snp.centerY)
            make.height.equalTo(NavigationBar.backButtonHeight)
        }
    }
    
    public func set(title: String?, subTitle: String?) {
        self.title = title
        self.subTitle = title
        
        if let subTitle = subTitle {
            titleLabel.numberOfLines = 2
            
            let textBorder = TextTag(strokeColor: .clear)
            textBorder.text = title
            textBorder.fillColor = .clear
            let attributedText = NSMutableAttributedString(textAttachment: textBorder)
            attributedText.addAttributes([.font: UIFont.boldSystemFont(ofSize: 16), .foregroundColor: tintColor ?? .white],
                                         range: NSRange(location: 0, length: attributedText.length))
            
            attributedText.append(NSAttributedString(string: "\n\(subTitle)",
                                                     attributes: [.foregroundColor : tintColor ?? .white,
                                                                  .font: UIFont.boldSystemFont(ofSize: 14)]))
            titleLabel.attributedText = attributedText
        } else {
            titleLabel.numberOfLines = 2
            
            titleLabel.attributedText = nil
            titleLabel.text = title
        }
    }
    
    public func set(title: String?) {
        set(title: title, subTitle: subTitle)
    }
    
    public func set(subTitle: String?) {
        set(title: title, subTitle: subTitle)
    }
}
